home *** CD-ROM | disk | FTP | other *** search
/ Java Interactive Reference Guide / Java Interactive Reference Guide.iso / autorun / source.dir / 00068_15.txt < prev    next >
Encoding:
Text File  |  1980-01-11  |  14.4 KB  |  502 lines

  1. /*
  2.  * @(#)Hangman.java    1.3  25 Oct 1995 10:12:02
  3.  * @author Patrick Chan
  4.  *
  5.  * Copyright (c) 1994-1995 Sun Microsystems, Inc. All Rights Reserved.
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software
  8.  * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
  9.  * without fee is hereby granted. 
  10.  * Please refer to the file http://java.sun.com/copy_trademarks.html
  11.  * for further important copyright and trademark information and to
  12.  * http://java.sun.com/licensing.html for further important licensing
  13.  * information for the Java (tm) Technology.
  14.  * 
  15.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  16.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  17.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  18.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  19.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  20.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  21.  * 
  22.  * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
  23.  * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
  24.  * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
  25.  * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
  26.  * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
  27.  * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
  28.  * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  SUN
  29.  * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
  30.  * HIGH RISK ACTIVITIES.
  31.  */
  32.  
  33. import java.awt.*;
  34. import java.applet.*;
  35. import java.io.*;
  36. import java.net.*;
  37.  
  38. public class Hangman extends java.applet.Applet implements Runnable {
  39.     /* This is the maximum number of incorrect guesses. */
  40.     final int maxTries = 5;
  41.  
  42.     /* This is the maximum length of a secret word. */
  43.     final int maxWordLen = 20;
  44.  
  45.     /* This buffer holds the letters in the secret word. */
  46.     char secretWord[];
  47.  
  48.     /* This is the length of the secret word. */
  49.     int secretWordLen;
  50.  
  51.     /* This buffer holds the letters which the user typed
  52.        but don't appear in the secret word. */
  53.     char wrongLetters[];
  54.  
  55.     /* This is the current number of incorrect guesses. */
  56.     int wrongLettersCount;
  57.  
  58.     /* This buffer holds letters that the user has successfully
  59.        guessed. */
  60.     char word[];
  61.  
  62.     /* Number of correct letters in 'word'. */
  63.     int wordLen;
  64.  
  65.     /* This is the font used to paint correctly guessed letters. */
  66.     Font wordFont;
  67.     FontMetrics wordFontMetrics;
  68.  
  69.     /* This is the sequence of images for Duke hanging on the gallows. */
  70.     Image hangImages[];
  71.     final int hangImagesWidth = 39;
  72.     final int hangImagesHeight = 58;
  73.  
  74.     // Dancing Duke related variables
  75.  
  76.     /* This thread makes Duke dance. */
  77.     Thread danceThread;
  78.  
  79.     /* These are the images that make up the dance animation. */
  80.     Image danceImages[];
  81.     private int danceImageWidths[] = { 70, 85, 87, 90, 87, 85, 70 };
  82.  
  83.     /* This is the maximum width and height of all the dance images. */
  84.     int danceHeight = 68;
  85.  
  86.     /* This variable holds the number of valid images in danceImages. */
  87.     int danceImagesLen = 0;
  88.  
  89.     /* These offsets refer to the dance images.  The dance images
  90.        are not of the same size so we need to add these offset 
  91.        in order to make the images "line" up. */
  92.     private int danceImageOffsets[] = { 8, 0, 0, 8, 18, 21, 27 };
  93.  
  94.     /* This represents the sequence to display the dance images
  95.        in order to make Duke "dance".  */
  96.     private int danceSequence[] = { 3, 4, 5, 6, 6, 5, 6, 6, 5, 4, 3, 
  97.             2, 1, 0, 0, 1, 2, 2, 1, 0, 0, 1, 2 };
  98.  
  99.     /* This is the current sequence number.  -1 implies
  100.        that Duke hasn't begun to dance. */
  101.     int danceSequenceNum = -1;
  102.  
  103.  
  104.     /* This variable is used to adjust Duke's x-position while
  105.        he's dancing. */
  106.     int danceX = 0;
  107.  
  108.     /* This variable specifies the currently x-direction of
  109.        Duke's dance.  1=>right and -1=>left. */
  110.     int danceDirection = 1;
  111.  
  112.     /* This is the stream for the dance music. */
  113.     AudioClip danceMusic;
  114.  
  115.     /**
  116.      * Initialize the applet. Resize and load images.
  117.      */
  118.     public void init() {
  119.         int i;
  120.  
  121.         // load in dance animation
  122.     danceMusic = getAudioClip(getCodeBase(), "rsrc/dance.au");
  123.     danceImages = new Image[40];
  124.  
  125.     for (i = 1; i < 8; i++) {
  126.         Image im = getImage(getCodeBase(), "rsrc/dancing-duke/T" + i + ".gif");
  127.  
  128.         if (im == null) {
  129.         break;
  130.         }
  131.         danceImages[danceImagesLen++] = im;
  132.         }
  133.  
  134.         // load in hangman image sequnce
  135.         hangImages = new Image[maxTries];
  136.         for (i=0; i<maxTries; i++) {
  137.         hangImages[i] = getImage(getCodeBase(), "rsrc/hanging-duke/h"+(i+1)+".gif");
  138.         }
  139.  
  140.         // initialize the word buffers.
  141.         wrongLettersCount = 0;
  142.         wrongLetters = new char[maxTries];
  143.  
  144.         secretWordLen = 0;
  145.         secretWord = new char[maxWordLen];
  146.  
  147.         word = new char[maxWordLen];
  148.         
  149.         wordFont = new java.awt.Font("Courier", Font.BOLD, 24);
  150.     wordFontMetrics = getFontMetrics(wordFont);
  151.  
  152.     resize((maxWordLen+1) * wordFontMetrics.charWidth('M') + maxWordLen * 3,
  153.             hangImagesHeight * 2 + wordFontMetrics.getHeight());
  154.     }
  155.  
  156.     /**
  157.      * Paint the screen.
  158.      */
  159.     public void paint(Graphics g) {
  160.         int imageW = hangImagesWidth;
  161.         int imageH = hangImagesHeight;
  162.         int baseH = 10;
  163.         int baseW = 30;
  164.         Font font;
  165.     FontMetrics fontMetrics;
  166.         int i, x, y;
  167.  
  168.         // draw gallows pole
  169.         g.drawLine(baseW/2, 0, baseW/2, 2*imageH - baseH/2);
  170.         g.drawLine(baseW/2, 0, baseW+imageW/2, 0);
  171.  
  172.         // draw gallows rope
  173.         g.drawLine(baseW+imageW/2, 0, baseW+imageW/2, imageH/3);
  174.  
  175.         // draw gallows base
  176.         g.fillRect(0, 2*imageH-baseH, baseW, baseH);
  177.  
  178.  
  179.         // draw list of wrong letters
  180.         font = new java.awt.Font("Courier", Font.PLAIN, 15);
  181.     fontMetrics = getFontMetrics(font);
  182.         x = imageW + baseW;
  183.         y = fontMetrics.getHeight();
  184.     g.setFont(font);
  185.     g.setColor(Color.red);
  186.         for (i=0; i<wrongLettersCount; i++) {
  187.             g.drawChars(wrongLetters, i, 1, x, y);
  188.             x += fontMetrics.charWidth(wrongLetters[i]) 
  189.         + fontMetrics.charWidth(' ');
  190.         }
  191.  
  192.         if (secretWordLen > 0) {
  193.         // draw underlines for secret word
  194.         int Mwidth = wordFontMetrics.charWidth('M');
  195.         int Mheight = wordFontMetrics.getHeight();
  196.         g.setFont(wordFont);
  197.         g.setColor(Color.black);
  198.         x = 0;
  199.         y = size().height - 1;
  200.         for (i=0; i<secretWordLen; i++) {
  201.         g.drawLine(x, y, x + Mwidth, y);
  202.         x += Mwidth + 3;
  203.         }
  204.  
  205.         // draw known letters in secret word
  206.         x = 0;
  207.         y = size().height - 3;
  208.             g.setColor(Color.blue);
  209.         for (i=0; i<secretWordLen; i++) {
  210.         if (word[i] != 0) {
  211.             g.drawChars(word, i, 1, x, y);
  212.         }
  213.         x += Mwidth + 3;
  214.         }
  215.  
  216.             if (wordLen < secretWordLen && wrongLettersCount > 0) {
  217.         // draw Duke on gallows
  218.         g.drawImage(hangImages[wrongLettersCount-1], 
  219.                     baseW, imageH/3, this);
  220.         }
  221.         }
  222.  
  223.     }
  224.  
  225.     public void update(Graphics g) {
  226.     if (wordLen == 0) {
  227.         g.clearRect(0, 0, size().width, size().height);
  228.             paint(g);
  229.     } else if (wordLen == secretWordLen) {
  230.             if (danceSequenceNum < 0) {
  231.         g.clearRect(0, 0, size().width, size().height);
  232.         paint(g);
  233.         danceSequenceNum = 0;
  234.         }
  235.             updateDancingDuke(g);
  236.         } else {
  237.             paint(g);
  238.         }
  239.     }
  240.  
  241.     void updateDancingDuke(Graphics g) {
  242.         int baseW = 30;
  243.         int imageH = hangImagesHeight;
  244.     int danceImageNum = danceSequence[danceSequenceNum];
  245.  
  246.     // first, clear Duke's current image
  247.     g.clearRect(danceX+baseW, imageH*2 - danceHeight, 
  248.             danceImageOffsets[danceImageNum]+danceImageWidths[danceImageNum], 
  249.             danceHeight);
  250.  
  251.         // update dance position
  252.     danceX += danceDirection;
  253.     if (danceX < 0) {
  254.         danceX = danceDirection = (int)Math.floor(Math.random() * 12) + 5;
  255.     } else if (danceX + baseW > size().width / 2) {
  256.         //danceDirection = -(int)Math.floor(Math.random() * 12) - 5;
  257.         danceDirection *= -1;
  258.     } else if (Math.random() > .9f) {
  259.         danceDirection *= -1;
  260.     }
  261.  
  262.         // update dance sequence
  263.     danceSequenceNum++;
  264.     if (danceSequenceNum >= danceSequence.length) {
  265.         danceSequenceNum = 0;
  266.         }
  267.  
  268.     // now paint Duke's new image
  269.     danceImageNum = danceSequence[danceSequenceNum];
  270.     if ((danceImageNum < danceImagesLen) && (danceImages[danceImageNum] != null)) {
  271.         g.drawImage(danceImages[danceImageNum], 
  272.         danceX+baseW+danceImageOffsets[danceImageNum], 
  273.         imageH*2 - danceHeight, this);
  274.     }
  275.     }
  276.  
  277.     public boolean keyDown(java.awt.Event evt, int key) {
  278.         int i;
  279.         boolean found = false;
  280.  
  281.         // start new game if user has already won or lost.
  282.         if (secretWordLen == wordLen || wrongLettersCount == maxTries) {
  283.             newGame();
  284.             return true;
  285.         }
  286.  
  287.         // check if valid letter
  288.         if (key < 'a' || key > 'z') {
  289.         play(getCodeBase(), "rsrc/beep.au");
  290.             return true;    
  291.         }
  292.         // check if already in secret word
  293.         for (i=0; i<secretWordLen; i++) {
  294.             if (key == word[i]) {
  295.                 found = true;
  296.         play(getCodeBase(), "rsrc/ding.au");
  297.                 return true;
  298.             }
  299.         }
  300.         // check if already in wrongLetters
  301.         if (!found) {
  302.         for (i=0; i<maxTries; i++) {
  303.         if (key == wrongLetters[i]) {
  304.             found = true;
  305.             play(getCodeBase(), "rsrc/ding.au");
  306.             return true;
  307.         }
  308.             }
  309.         }
  310.         // is letter in secret word? If so, add it.
  311.         if (!found) {
  312.             for (i=0; i<secretWordLen; i++) {
  313.                 if (key == secretWord[i]) {
  314.                     word[i] = (char)key;
  315.                     wordLen++;
  316.                     found = true;
  317.                 }
  318.             }
  319.             if (found) {
  320.                 if (wordLen == secretWordLen) {
  321.             play(getCodeBase(), "rsrc/whoopy.au");
  322.                     startDukeDancing();
  323.         } else {
  324.             play(getCodeBase(), "rsrc/ah.au");
  325.                 }
  326.             }
  327.         }
  328.         // wrong letter; add to wrongLetters
  329.         if (!found) {
  330.         if (wrongLettersCount < wrongLetters.length) {
  331.         wrongLetters[wrongLettersCount++] = (char)key;
  332.                 if (wrongLettersCount < maxTries) {
  333.             play(getCodeBase(), "rsrc/ooh.au");
  334.                 } else {
  335.                     // show the answer
  336.                     for (i=0; i<secretWordLen; i++) {
  337.                         word[i] = secretWord[i];
  338.                     }
  339.             play(getCodeBase(), "rsrc/scream.au");
  340.                 }
  341.             }
  342.         }
  343.         if (wordLen == secretWordLen) {
  344.             danceSequenceNum = -1;
  345.         }
  346.         repaint();
  347.     return true;
  348.     }
  349.  
  350.     /**
  351.      * Grab the focus and restart the game.
  352.      */
  353.     public boolean mouseDown(java.awt.Event evt, int x, int y) {
  354.         int i;
  355.  
  356.         // grab focus to get keyDown events
  357.         requestFocus();
  358.  
  359.         if (secretWordLen > 0 && 
  360.            (secretWordLen == wordLen || wrongLettersCount == maxTries)) {
  361.         newGame();
  362.         } else {
  363.         play(getCodeBase(), "rsrc/beep.au");
  364.         }
  365.     return true;
  366.     }
  367.  
  368.     /**
  369.      * Starts a new game.  Chooses a new secret word
  370.      * and clears all the buffers
  371.      */
  372.     public void newGame() {
  373.         int i;
  374.  
  375.         // stop animation thread.
  376.         danceThread = null;
  377.  
  378.         // pick secret word
  379.         String s = wordlist[(int)Math.floor(Math.random() * wordlist.length)];
  380.         
  381.         secretWordLen = Math.min(s.length(), maxWordLen);
  382.         for (i=0; i<secretWordLen; i++) {
  383.             secretWord[i] = s.charAt(i);
  384.         }
  385.  
  386.         // clear word buffers
  387.         for (i=0; i<maxWordLen; i++) {
  388.             word[i] = 0;
  389.         }
  390.         wordLen = 0;
  391.         for (i=0; i<maxTries; i++) {
  392.             wrongLetters[i] = 0;
  393.         }
  394.         wrongLettersCount = 0;
  395.  
  396.         repaint();
  397.     }
  398.  
  399.     /**
  400.      * Start the applet.
  401.      */
  402.     public void start() {
  403.     requestFocus();
  404.         // Start a new game only if user has won or lost; otherwise
  405.         // retain the same game.
  406.         if (secretWordLen == wordLen || wrongLettersCount == maxTries) {
  407.             newGame();
  408.         }
  409.     }
  410.  
  411.     /**
  412.      * Stop the applet.  Stop the danceThread.
  413.      */
  414.     public void stop() {
  415.     danceThread = null;
  416.     }
  417.  
  418.     /**
  419.      * Run Duke's dancing animation. This methods is called by class Thread.
  420.      * @see java.lang.Thread
  421.      */
  422.     public void run() {
  423.     Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
  424.  
  425.         // start the dancing music.
  426.     danceMusic.loop();
  427.  
  428.         // increment the sequence count and invoke the paint method.
  429.     while (size().width > 0 && size().height > 0 && danceThread != null) {
  430.         repaint();
  431.         try {Thread.sleep(100);} catch (InterruptedException e){}
  432.     }
  433.  
  434.         // The dance is done so stop the music.
  435.     danceMusic.stop();
  436.     }
  437.  
  438.     /**
  439.      * Starts Duke's dancing animation.
  440.      */
  441.     private void startDukeDancing () {
  442.     if (danceThread == null) {
  443.         danceThread = new Thread(this);
  444.         danceThread.start();
  445.     }
  446.     }
  447.  
  448.     // Added by Kevin A. Smith 10/25/95
  449.     public String getAppletInfo() {
  450.        return "Author: Patrick Chan\nVersion 1.3";
  451.     }
  452.  
  453.  
  454.     /* This is the hangman's limited word list. */
  455.     String wordlist[] = {
  456.         "abstraction",
  457.         "ambiguous",
  458.         "arithmetic",
  459.         "backslash",
  460.         "bitmap",
  461.         "circumstance",
  462.         "combination",
  463.         "consequently",
  464.         "consortium",
  465.         "decrementing",
  466.         "dependency",
  467.         "disambiguate",
  468.         "dynamic",
  469.         "encapsulation",
  470.         "equivalent",
  471.         "expression",
  472.         "facilitate",
  473.         "fragment",
  474.         "hexadecimal",
  475.         "implementation",
  476.         "indistinguishable",
  477.         "inheritance",
  478.         "internet",
  479.         "java",
  480.         "localization",
  481.         "microprocessor",
  482.         "navigation",
  483.         "optimization",
  484.         "parameter",
  485.         "patrick",
  486.         "pickle",
  487.         "polymorphic",
  488.         "rigorously",
  489.         "simultaneously",
  490.         "specification",
  491.         "structure",
  492.         "lexical",
  493.         "likewise",
  494.         "management",
  495.         "manipulate",
  496.         "mathematics",
  497.         "hotjava",
  498.         "vertex",
  499.         "unsigned",
  500.         "traditional"};
  501. }
  502.